package com.fast.thread;

import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class ThreadPoolRunTest {

    @Resource(name = "wz-consume")
    private Executor consumerPool;
    @Autowired
    @Qualifier("wz-produce")
    private Executor productPool;

    private final static InheritableThreadLocal<String> context = new InheritableThreadLocal<>();


    @PostConstruct
    private void init() {
        new Thread(() -> {
            // runTest();
            int count = 10;
            while (true) {
                List<String> threadPoolId = GlobalThreadPoolManage.listThreadPoolId();
                if (threadPoolId.isEmpty()) {
                    //把这个后置处理器关闭， BizExecutorConfigProcessor,就可以扫描并注册了
                    log.error("开启 BizExecutorConfigProcessor 导致 threadPoolId 是空的，没有装饰上 GlobalThreadPoolManage.listThreadPoolId={}", threadPoolId);
                } else {
                    log.info("[正常]threadPoolId不空！GlobalThreadPoolManage.listThreadPoolId={}", threadPoolId);
                }
                try {
                    TimeUnit.MILLISECONDS.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                if (--count <= 0) {
                    break;
                }
            }
        }).start();

    }

    private void runTest() {
        int count = 3;
        try {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            String data = RandomUtil.randomString(32);

            MDC.put("traceId", data);
//            log.info("本次设置的数据是：{}", MDC.get("traceId"));
            context.set(data);

            for (int i = 0; i < count; i++) {
                consumerPool.execute(() -> {
                    try {
                        TimeUnit.SECONDS.sleep(5);
                        showData();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });

                productPool.execute(() -> {
                    try {
                        TimeUnit.SECONDS.sleep(10);
                        showData();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });
                //  print("consumerPool", consumerPool);
                // print("productPool", productPool);

            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    private void showData() {
        Thread thread = Thread.currentThread();
        String thStr = "" + thread.getThreadGroup() + "-" + thread.getName() + "-" + thread.getId();
        String data = context.get();
        // log.info("thread={} data= {}", thStr, data);
        MDC.put("traceId", data);
        String traceId = MDC.get("traceId");
        log.info(" MDC thread={} MDC data={}", thStr, traceId);
    }

    private void print(String name, ThreadPoolExecutor pool) {

        log.info("");
        log.info("===============================");
        log.info("pool.name = {}", name);
        log.info("pool.getPoolSize = {}", pool.getPoolSize());
        log.info("pool.getMaximumPoolSize = {}", pool.getMaximumPoolSize());
        log.info("pool.getCorePoolSize = {}", pool.getCorePoolSize());
        log.info("pool.queueSize = {}", pool.getQueue().size());
        log.info("pool.getActiveCount = {}", pool.getActiveCount());
        log.info("pool.getTaskCount = {}", pool.getTaskCount());
        log.info("pool.getCompletedTaskCount = {}", pool.getCompletedTaskCount());
        log.info("===============================");
        log.info("");

    }
}
